package cn.huiyunche.base.service.interfaces.impl;


import cn.huiyunche.base.service.enums.ImportResultCodeEnum;
import cn.huiyunche.base.service.enums.VehicleFuelImportResultEnum;
import cn.huiyunche.base.service.form.ScPriceconfOcValidateLogForm;
import cn.huiyunche.base.service.interfaces.VehicleFuelImportService;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.query.DVehicleClassifyQuery;
import cn.huiyunche.base.service.query.ScPriceconfOcValidateQueryConditions;
import cn.huiyunche.base.service.vo.PageVo;
import cn.huiyunche.base.service.vo.ScBaseCvTankvolumeVo;
import cn.huiyunche.base.service.vo.ScPriceconfOcValidateLogVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Fleix on 2017/5/8.
 */
@Service
public class VehicleFuelImportServiceImpl implements VehicleFuelImportService {

    private static final Logger logger = LoggerFactory.getLogger(VehicleFuelImportServiceImpl.class);

    @Autowired
    private ScPriceconfOcValidateLogMapper scPriceconfOcValidateLogMapper;

    @Autowired
    private DVehicleClassifyMapper dVehicleClassifyMapper;

    @Autowired
    private ScBaseCvTankvolumeMapper scBaseCvTankvolumeMapper;

    @Autowired
    private ScPriceconfOcMapper scPriceconfOcMapper;

    @Autowired
    private ScPriceconfOcImportLogMapper scPriceconfOcImportLogMapper;


    @Override
    public Map<String, Object> selectListByConditions(PageVo pageVo, ScPriceconfOcValidateQueryConditions conditions) throws Exception {
        logger.info("VehicleFuelImportServiceImpl.selectListByConditions params : {}, {}", pageVo, conditions);
        Map<String, Object> map = new HashMap<>();
        ScPriceconfOcValidateLogExample example = new ScPriceconfOcValidateLogExample();
        example.createCriteria().andBatchIdEqualTo(conditions.getBatchId());
        example.setLimitStart(pageVo.getStartIndex());
        example.setLimitEnd(pageVo.getPageSize());
        List<ScPriceconfOcValidateLogVo> list = scPriceconfOcValidateLogMapper.selectByConditions(pageVo.getStartIndex(),pageVo.getPageSize(),conditions.getBatchId());
        if (list.size() > 0) {
            for(ScPriceconfOcValidateLogVo sc : list) {
                if (sc.getValidateResultCode().equals(ImportResultCodeEnum.ERROR.getValue())){
                    sc.setValidateResultCodeString(ImportResultCodeEnum.ERROR.getText());
                }else if (sc.getValidateResultCode().equals(ImportResultCodeEnum.WARN.getValue())){
                    sc.setValidateResultCodeString(ImportResultCodeEnum.WARN.getText());
                }else if(sc.getValidateResultCode().equals(ImportResultCodeEnum.RIGHT.getValue())){
                    sc.setValidateResultCodeString(ImportResultCodeEnum.RIGHT.getText());
                }
                if (StringUtils.isEmpty(sc.getImportResult())){
                    sc.setImportResult("未导入");
                }

            }
        }
        if (null != pageVo) {
            pageVo.setTotalRecord(scPriceconfOcValidateLogMapper.countByExample(example));
        }
        map.put("list", list);
        if (null != pageVo) {
            map.put("page", pageVo);
        }
        return map;
    }

    @Override
    public ScPriceconfOcValidateLog selectByPrimaryKey(Integer id) throws Exception {
        logger.info("VehicleFuelImportServiceImpl.selectByPrimaryKey param : {}", id);
        if (null == id) {
            logger.error("VehicleFuelImportServiceImpl.selectByPrimaryKey param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }
        return scPriceconfOcValidateLogMapper.selectByPrimaryKey(id);
    }

    @Override
    public void update(ScPriceconfOcValidateLogForm form, BindingResult br) throws Exception {
        logger.info("VehicleFuelImportServiceImpl.update param : {}", form);
        if (form == null) {
            logger.error("VehicleFuelImportServiceImpl.update param form must not be null");
            throw new IllegalArgumentException("表单不能为空");
        }
        ScPriceconfOcValidateLog log = new ScPriceconfOcValidateLog();
        BeanUtils.copyProperties(form, log);
        this.updateSelective(log);
    }

    public void updateSelective(ScPriceconfOcValidateLog log) {
        logger.info("VehicleFuelImportServiceImpl.updateSelective param : {}", log);
        if (null == log) {
            logger.error("VehicleFuelImportServiceImpl.updateSelective param currentOc must not be null");
            throw new IllegalArgumentException("车型油耗变动不能为空");
        }
        scPriceconfOcValidateLogMapper.updateByPrimaryKeySelective(log);
    }

    @Override
    public void del(Integer id) throws Exception {
        logger.info("VehicleFuelImportServiceImpl.del param : {}", id);
        if ( null ==  id || 0 == id.intValue() ) {
            logger.error("VehicleFuelImportServiceImpl.del param id must not be null");
            throw new IllegalArgumentException("主键不能为空");
        }
        ScPriceconfOcValidateLog Oc = selectByPrimaryKey(id);
        if ( null == Oc ){
            logger.error("VehicleFuelImportServiceImpl.del mile is null");
            throw new BusinessException("记录不存在");
        }
        scPriceconfOcValidateLogMapper.deleteByPrimaryKey(id);
    }

    public void deleteAll() throws Exception{
        //清空表数据
        ScPriceconfOcValidateLogExample example3 = new ScPriceconfOcValidateLogExample();
//        List<ScPriceconfOcValidateLogVo> forms = scPriceconfOcValidateLogMapper.selectByConditions(example3);
//        int i = 0;
//        if (forms.size() >0 ) {
//            for (ScPriceconfOcValidateLogVo vo : forms){
//                if (vo.getImportResultCode().equals(ImportResultCodeEnum.SUCCESS.getValue())){
//                    i= i+1;
//                }
//            }
//            if (forms.size() == i){
//                scPriceconfOcValidateLogMapper.deleteAll();
//                scPriceconfOcImportLogMapper.deleteAll();
//            }
//        }
    }

    @Override
    public void importExcel(List<ScPriceconfOcValidateLogVo> list, String batchId) throws Exception {
        logger.info("import start: VehicleFuelImportServiceImpl job time: {}", new Date().toString());
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for(ScPriceconfOcValidateLogVo vo : list){
                vo.setEffectiveDate(StringUtils.isEmpty(vo.getEffectiveDateString()) ? null:sdf.parse(vo.getEffectiveDateString()));
                vo.setBatchId(batchId);
            }
            scPriceconfOcValidateLogMapper.insertList(list);
        } catch (Exception e) {
            logger.error("VehicleFuelImportServiceImpl.import e:" + e.getMessage());
            throw new BusinessException("导入失败！");
        }
    }

    @Override
    public void checkData(String batchId) throws Exception {
        //清空日志表需要导入的数据
        ScPriceconfOcValidateLogExample example = new ScPriceconfOcValidateLogExample();
        example.createCriteria().andBatchIdEqualTo(batchId);
        List<ScPriceconfOcValidateLog> list = scPriceconfOcValidateLogMapper.selectByExample(example);
        if (list.size() == 0) {
            return;
        }
        for (ScPriceconfOcValidateLog sc : list) {
            sc.setValidateResultCode(null);
            sc.setValidateResult(null);
        }
        scPriceconfOcValidateLogMapper.validateResultBatchUpdate(list);
        //校验车型是否重复
        List<ScPriceconfOcValidateLog> list1 = scPriceconfOcValidateLogMapper.selectVehicleRepeat(batchId);
        if (list1.size() > 0) {
            for (ScPriceconfOcValidateLog sc : list1) {
                writeResult(sc, VehicleFuelImportResultEnum.VEHICLE_REPEAT.getText(), ImportResultCodeEnum.ERROR.getValue());
            }
            scPriceconfOcValidateLogMapper.validateResultBatchUpdate(list1);
        }

        ScPriceconfOcValidateLogExample example1 = new ScPriceconfOcValidateLogExample();
        example1.createCriteria().andBatchIdEqualTo(batchId);
        List<ScPriceconfOcValidateLog> list2 = scPriceconfOcValidateLogMapper.selectByExample(example1);
        if (list2.size() > 0) {
            for (ScPriceconfOcValidateLog sc : list2) {
                //校验车型是否为空
                if (StringUtils.isEmpty(sc.getVehicleClassName())) {
                    writeResult(sc, VehicleFuelImportResultEnum.VEHICLE_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验车型ID是否为空
                if (sc.getVehicleClassId() == null) {
                    writeResult(sc, VehicleFuelImportResultEnum.VEHICLE_ID_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验邮箱容积是否为空
                if (sc.getTankVolume() == null) {
                    writeResult(sc, VehicleFuelImportResultEnum.TANK_VOLUME_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验油品是否为空
                if (StringUtils.isEmpty(sc.getOilTypeName())) {
                    writeResult(sc, VehicleFuelImportResultEnum.OIL_TYPE_NAME_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                }
                //校验油耗是否为空
                if (sc.getStandardOc() == null) {
                    writeResult(sc, VehicleFuelImportResultEnum.STANDARD_OC_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                } else {
                    //校验公里数是否大于零
                    if (sc.getStandardOc().compareTo(BigDecimal.ZERO) == -1) {
                        writeResult(sc, VehicleFuelImportResultEnum.STANDARD_OC_THAN_ZERO.getText(), ImportResultCodeEnum.ERROR.getValue());
                    }
                }
                //校验生效日期是否为空
                if (sc.getEffectiveDate() == null) {
                    writeResult(sc, VehicleFuelImportResultEnum.EFFECTIVE_DATE_NOT_NULL.getText(), ImportResultCodeEnum.ERROR.getValue());
                } else {
                    //校验生效日期是否大于当前日期
                    if ((sc.getEffectiveDate().getTime()) < (new Date().getTime())) {
                        writeResult(sc, VehicleFuelImportResultEnum.EFFECTIVE_DATE_THAN_NOW.getText(), ImportResultCodeEnum.ERROR.getValue());
                    }
                    //校验生效日期是否大于已存在生效日期
                    ScPriceconfOc scPriceconfOc = scPriceconfOcMapper.queryMaxEffectiveDate(sc.getVehicleClassId());
                    if (scPriceconfOc != null && scPriceconfOc.getEffectiveDate().getTime() >= sc.getEffectiveDate().getTime()){
                        writeResult(sc, VehicleFuelImportResultEnum.EFFECTIVE_DATE_THAN_BEFORE.getText(), ImportResultCodeEnum.ERROR.getValue());
                    }
                }

            }
            scPriceconfOcValidateLogMapper.validateResultBatchUpdate(list2);
        }
        //校验车型是否存在
        ScPriceconfOcValidateLogExample example2 = new ScPriceconfOcValidateLogExample();
        example2.createCriteria().andVehicleClassNameIsNotNull().andVehicleClassIdIsNotNull().andOilTypeNameIsNotNull();
        List<ScPriceconfOcValidateLog> list3 = scPriceconfOcValidateLogMapper.selectByExample(example2);
        DVehicleClassifyExample example3 = new DVehicleClassifyExample();
        List<DVehicleClassifyQuery> list4 = dVehicleClassifyMapper.selectAndFuelTypeName(example3);
        if (list3.size() > 0 && list4.size() > 0) {
            List<ScPriceconfOcValidateLog> list6 = new ArrayList<ScPriceconfOcValidateLog>();
            for (ScPriceconfOcValidateLog sc : list3) {
                list6.add(sc);
            }
            for (DVehicleClassifyQuery dr : list4) {
                for (ScPriceconfOcValidateLog sc : list3) {
                    if (sc.getVehicleClassName().equals(dr.getVehicleClassifyName()) && sc.getVehicleClassId().equals(dr.getVehicleClassifyId())
                            && sc.getOilTypeName().equals(dr.getFuelTypeName())) {
                        list6.remove(sc);
                    }
                }
            }
            if (list6.size() > 0) {
                for (ScPriceconfOcValidateLog sc : list6) {
                    writeResult(sc, VehicleFuelImportResultEnum.VEHICLE_NOT_EXIST.getText(), ImportResultCodeEnum.WARN.getValue());
                }
                scPriceconfOcValidateLogMapper.validateResultBatchUpdate(list6);
            }
        }
        //校验正确
        ScPriceconfOcValidateLogExample example4 = new ScPriceconfOcValidateLogExample();
        example4.createCriteria().andValidateResultIsNull();
        List<ScPriceconfOcValidateLog> list5 = scPriceconfOcValidateLogMapper.selectByExample(example4);
        if (list5.size() > 0) {
            for (ScPriceconfOcValidateLog sc : list5) {
                sc.setValidateResultCode(ImportResultCodeEnum.RIGHT.getValue());
            }
            scPriceconfOcValidateLogMapper.validateResultBatchUpdate(list5);
        }

    }

    @Override
    public void importOcAndTank(String batchId) throws Exception {
        //获取所有要插入的数据
        ScPriceconfOcValidateLogExample example = new ScPriceconfOcValidateLogExample();
        example.createCriteria().andValidateResultCodeBetween(ImportResultCodeEnum.WARN.getValue(),ImportResultCodeEnum.RIGHT.getValue()).andBatchIdEqualTo(batchId);
        List<ScPriceconfOcValidateLog> listAll = scPriceconfOcValidateLogMapper.selectByExample(example);
        if(listAll.size() == 0){
            throw new BusinessException("导入数据为空");
        }
        //去掉已经导入成功的数据
        List<ScPriceconfOcValidateLog> listData = new ArrayList<ScPriceconfOcValidateLog>();
        for (ScPriceconfOcValidateLog sc : listAll) {
            listData.add(sc);
        }
        for (ScPriceconfOcValidateLog sc : listAll) {
            ScPriceconfOcImportLogExample exampleLog = new ScPriceconfOcImportLogExample();
            exampleLog.createCriteria().andDataIdEqualTo(sc.getId()).andImportResultCodeEqualTo(ImportResultCodeEnum.SUCCESS.getValue());
            List<ScPriceconfOcImportLog> listLog = scPriceconfOcImportLogMapper.selectByExample(exampleLog);
            if (listLog.size() > 0){
                listData.remove(sc);
            }
        }

        if (listData.size() > 0) {
            //获取车型信息
            DVehicleClassifyExample example1 = new DVehicleClassifyExample();
            List<DVehicleClassifyQuery> listVehicle = dVehicleClassifyMapper.selectAndFuelTypeName(example1);
            //获取需要添加车型的数据
            ScPriceconfOcValidateLogExample example2 = new ScPriceconfOcValidateLogExample();
            example2.createCriteria().andValidateResultCodeEqualTo(ImportResultCodeEnum.WARN.getValue());
            List<ScPriceconfOcValidateLog> listAdd = scPriceconfOcValidateLogMapper.selectByExample(example2);
            if (listAdd.size() > 0) {
                List<DVehicleClassify> list = new ArrayList<DVehicleClassify>();
                for (ScPriceconfOcValidateLog sc : listData) {
                    DVehicleClassify dv = new DVehicleClassify();
                    dv.setVehicleClassifyName(sc.getVehicleClassName());
//                dv.setFuelTypeId(sc.getOilTypeId());
                    dv.setFuelConsumption(sc.getStandardOc());
                    list.add(dv);
                }
                //插入新增线路
                dVehicleClassifyMapper.insertList(list);
            }

            if (listVehicle.size() > 0) {
                for (DVehicleClassifyQuery dr : listVehicle) {
                    for (ScPriceconfOcValidateLog sc : listData) {
                        if (sc.getVehicleClassName().equals(dr.getVehicleClassifyName()) && sc.getVehicleClassId().equals(dr.getVehicleClassifyId())
                                && sc.getOilTypeName().equals(dr.getFuelTypeName())) {
                            ScPriceconfOc oc = new ScPriceconfOc();
                            oc.setVehicleTypeId(dr.getVehicleClassifyId());
                            oc.setCurrentValue(sc.getStandardOc());
                            oc.setEffectiveDate(sc.getEffectiveDate());
                            oc.setGmtCreate(new Date());
                            oc.setGmtUpdate(new Date());
                            ScPriceconfOcImportLog scPriceconfOcImportLog = new ScPriceconfOcImportLog();
                            try {
                                scPriceconfOcMapper.insert(oc);
                                ScBaseCvTankvolumeExample example3 = new ScBaseCvTankvolumeExample();
                                example3.createCriteria().andCvTypeIdEqualTo(dr.getVehicleClassifyId());
                                List<ScBaseCvTankvolumeVo> list = scBaseCvTankvolumeMapper.selectByExample(example3);
                                if (list.size() > 0) {
                                    ScBaseCvTankvolume tankvolumeUpdate = new ScBaseCvTankvolume();
                                    tankvolumeUpdate.setId(list.get(0).getId());
                                    tankvolumeUpdate.setTankVolume(new BigDecimal(sc.getTankVolume()));
                                    tankvolumeUpdate.setGmtUpdate(new Date());
                                    scBaseCvTankvolumeMapper.updateByPrimaryKeySelective(tankvolumeUpdate);
                                } else {
                                    ScBaseCvTankvolume tankvolume = new ScBaseCvTankvolume();
                                    tankvolume.setCvTypeId(dr.getVehicleClassifyId());
                                    tankvolume.setTankVolume(new BigDecimal(sc.getTankVolume()));
                                    tankvolume.setGmtCreate(new Date());
                                    tankvolume.setGmtUpdate(new Date());
                                    scBaseCvTankvolumeMapper.insert(tankvolume);
                                }
                                writeScPriceconfOcImportLog(scPriceconfOcImportLog, ImportResultCodeEnum.SUCCESS.getValue(), ImportResultCodeEnum.SUCCESS.getText(), sc.getId());
                                scPriceconfOcImportLogMapper.insert(scPriceconfOcImportLog);
                            } catch (Exception e) {
                                writeScPriceconfOcImportLog(scPriceconfOcImportLog, ImportResultCodeEnum.FAIL.getValue(), ImportResultCodeEnum.FAIL.getText(), sc.getId());
                                scPriceconfOcImportLogMapper.insert(scPriceconfOcImportLog);
                                throw new Exception("插入异常");
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void delete() throws Exception {
        try {
            scPriceconfOcValidateLogMapper.deleteAll();
            scPriceconfOcImportLogMapper.deleteAll();
        }catch (Exception e){
            throw new BusinessException(e.getMessage());
        }

    }

    @Override
    public void checkInvalidDate() throws Exception {
        //校验ScPriceconfOc失效日期
        List<ScPriceconfOc> list1 = scPriceconfOcMapper.selectVehicleTypeIdRepeat();
        if (list1.size() > 0) {
            for (ScPriceconfOc sc1 : list1) {
                if (sc1.getInvalidDate() == null) {
                    for (ScPriceconfOc sc2 : list1) {
                        if (sc1.getVehicleTypeId().equals(sc2.getVehicleTypeId()) && sc1.getId() != sc2.getId()
                                && sc1.getEffectiveDate().getTime() < sc2.getEffectiveDate().getTime()) {
                            ScPriceconfOc scPriceconfOc = new ScPriceconfOc();
                            scPriceconfOc.setId(sc1.getId());
                            scPriceconfOc.setInvalidDate(sc2.getEffectiveDate());
                            scPriceconfOc.setGmtUpdate(new Date());
                            scPriceconfOcMapper.updateByPrimaryKeySelective(scPriceconfOc);
                        }
                    }
                }
            }
        }
    }


    private ScPriceconfOcValidateLog writeResult(ScPriceconfOcValidateLog sc, String result, Integer resultCode) {
        if (StringUtils.isEmpty(sc.getValidateResult())) {
            sc.setValidateResult(result);
        } else {
            sc.setValidateResult(sc.getValidateResult() + "," + result);
        }
        if (sc.getValidateResultCode() != null && resultCode == ImportResultCodeEnum.WARN.getValue()
                && sc.getValidateResultCode() == ImportResultCodeEnum.ERROR.getValue()) {

        } else {
            sc.setValidateResultCode(resultCode);
        }
        return sc;
    }

    private ScPriceconfOcImportLog writeScPriceconfOcImportLog(ScPriceconfOcImportLog scPriceconfOcImportLog, Integer resultCode, String result, Integer id) {
        scPriceconfOcImportLog.setImportResultCode(resultCode);
        scPriceconfOcImportLog.setImportResult(result);
        scPriceconfOcImportLog.setDataId(id);
        scPriceconfOcImportLog.setGmtCreate(new Date());
        scPriceconfOcImportLog.setGmtUpdate(new Date());
        return scPriceconfOcImportLog;
    }
}
